package com.example.hospitalsystem.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.hospitalsystem.exception.HospitalSystemServiceException;
import com.example.hospitalsystem.mapper.*;
import com.example.hospitalsystem.pojo.dto.buylog.LogPageQueryDto;
import com.example.hospitalsystem.pojo.dto.patient.AddPatientDto;
import com.example.hospitalsystem.pojo.dto.patient.ChangePatientDto;
import com.example.hospitalsystem.pojo.dto.patient.PatientPageQueryDto;
import com.example.hospitalsystem.pojo.dto.registration.UpdateBalanceDTO;
import com.example.hospitalsystem.pojo.entity.*;
import com.example.hospitalsystem.pojo.vo.PatientItemVO;
import com.example.hospitalsystem.pojo.vo.PatientPrescriptionPharmacyVO;
import com.example.hospitalsystem.result.Result;
import com.example.hospitalsystem.result.ResultCodeEnum;
import com.example.hospitalsystem.service.PatientService;
import com.example.hospitalsystem.utils.JwtHelper;
import com.example.hospitalsystem.utils.PaginationResult;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PatientServiceImpl extends ServiceImpl<PatientMapper, Patient>
        implements PatientService {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private JwtHelper jwtHelper;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private  PatientMapper patientMapper;
    @Autowired
    private PrescriptionMapper prescriptionMapper;
    @Autowired
    private PrescriptionPharmacyMapper prescriptionPharmacyMapper;
    @Autowired
    private BuyMedicineLogMapper buyMedicineLogMapper;
    @Autowired
    private ConsultationMapper consultationMapper;


    @Override
    public Result<Object> getAllPatientInfo(PatientPageQueryDto patientPageQueryDto) {

        int pageNum=patientPageQueryDto.getPageNum();
        int pageSize=patientPageQueryDto.getPageSize();
        Page<Patient> adminPage=new Page<>(pageNum,pageSize);

        if(patientPageQueryDto.getPatientName()==null||patientPageQueryDto.getPatientName()==""){
            //创建page对象
            IPage<Patient>adminIPage=patientMapper.selectPage(adminPage,null);
            return Result.build(adminIPage, 200,"管理员获取所有患者信息成功");
        }else{
            Page<Patient> patientPage=new Page<>(pageNum,pageSize);
            LambdaQueryWrapper<Patient> lambdaQueryWrapper=new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(Patient::getPatientName,patientPageQueryDto.getPatientName());
            IPage<Patient> patientIPage= patientMapper.selectPage(patientPage,lambdaQueryWrapper);
            return Result.build(patientIPage, 200,"管理员获取指定生信息成功");
        }

    }

    @Override
    public Result<Object> changePatientInfo(ChangePatientDto changePatientDto) {

        LambdaUpdateWrapper<Patient> lambdaUpdateWrapper=new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(Patient::getPatientId,changePatientDto.getPatientId())
                .set(Patient::getPatientName,changePatientDto.getPatientName())
                .set(Patient::getAge,changePatientDto.getAge())
                .set(Patient::getGender,changePatientDto.getGender())
                .set(Patient::getContact,changePatientDto.getContact())
                .set(Patient::getAddress, changePatientDto.getAddress());
        this.update(lambdaUpdateWrapper);
        return Result.build(null,"更改患者信息成功");
    }

    @Override
    public Result<Object> addPatientInfo(Patient patient) {
        String token=request.getHeader("Authorization");
        int userId= jwtHelper.getUserId(token);
        patient.setUserId(userId);
        LambdaQueryWrapper<Patient> patientLambdaQueryWrapper=new LambdaQueryWrapper<>();
        patientLambdaQueryWrapper.eq(Patient::getUserId,userId);

        Patient patient1=baseMapper.selectOne(patientLambdaQueryWrapper);

        if(patient1==null){
            baseMapper.insert(patient);
            return Result.build(null,200,"完善换着信息成功");
        }else{
            LambdaUpdateWrapper<Patient> patientLambdaUpdateWrapper=new LambdaUpdateWrapper<>();
            patientLambdaUpdateWrapper.eq(Patient::getUserId,patient.getUserId());

            this.update(patient,patientLambdaUpdateWrapper);

            baseMapper.insert(patient);
            return Result.build(null,200,"更新换着信息成功");
        }

    }

    @Override
    public Result<Object> deletePatientInfo(String password) {
        String token=request.getHeader("Authorization");
        int userId= jwtHelper.getUserId(token);
        LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserId,userId);
        User user=userMapper.selectOne(lambdaQueryWrapper);

        if(!user.getPassword().equals(password)){
            return Result.build(null, ResultCodeEnum.PASSWORD_ERROR);
        }
        int is=userMapper.delete(lambdaQueryWrapper);
        if(is>0){
            return Result.build(null,"注销患者信息成功");
        }
        return Result.build(null,"注销换着信息失败");
    }

    /**
     * 返回患者列表
     * @param patientId
     * @return
     */
    @Override
    public List<PatientItemVO> getPatientItem(Integer patientId) {
        LambdaQueryWrapper<Patient> patientLambdaQueryWrapper = new LambdaQueryWrapper<>();
        patientLambdaQueryWrapper.eq(Patient::getPatientId, patientId);
        List<Patient> patientList = patientMapper.selectList(patientLambdaQueryWrapper);


        PatientItemVO patientItemVO = new PatientItemVO();
        List<PatientItemVO> patientItemVOS = new ArrayList<>();
        for (Patient patient : patientList) {
            patientItemVO.setPatientName(patient.getPatientName());
            patientItemVOS.add(patientItemVO);
        }

        return patientItemVOS;
    }

    /**
     * 患者支付药品费用
     * @param patientId
     * @return
     */
    @Override
    @Transactional
    public Result<Object> paymentAmountByPatient(Integer patientId) {
        String token=request.getHeader("Authorization");
        int userId= jwtHelper.getUserId(token);

        //确认患者信息
        LambdaQueryWrapper<Patient> patientLambdaQueryWrapper = new LambdaQueryWrapper<>();
        patientLambdaQueryWrapper.eq(Patient::getUserId, userId);
        Patient patient = patientMapper.selectOne(patientLambdaQueryWrapper);

        //获取该患者处方信息
        LambdaQueryWrapper<Prescription> prescriptionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        prescriptionLambdaQueryWrapper.eq(Prescription::getPatientId, patient.getPatientId());
        Prescription prescription = prescriptionMapper.selectOne(prescriptionLambdaQueryWrapper);

        //获取该患者药品信息
        LambdaQueryWrapper<PrescriptionPharmacy> prescriptionPharmacyLambdaQueryWrapper = new LambdaQueryWrapper<>();
        prescriptionPharmacyLambdaQueryWrapper.eq(PrescriptionPharmacy::getPrescriptionId, prescription.getPrescriptionId());
        List<PrescriptionPharmacy> prescriptionPharmacies = prescriptionPharmacyMapper.selectList(prescriptionPharmacyLambdaQueryWrapper);

        //遍历该患者药品信息，取出每个药品单价
        List<UpdateBalanceDTO> allMedicinePrices = new ArrayList<>();
        for (PrescriptionPharmacy pp : prescriptionPharmacies) {
            UpdateBalanceDTO updateBalanceDTO = new UpdateBalanceDTO();
            updateBalanceDTO.setPatientId(patientId);
            updateBalanceDTO.setUnitPrice(pp.getUnitPrice());
            updateBalanceDTO.setMedicineId(pp.getMedicineId());
            allMedicinePrices.add(updateBalanceDTO);
        }

        //封装HashMap
        HashMap<Integer, Integer> map = new HashMap<>();
        for (UpdateBalanceDTO medicinePrice : allMedicinePrices) {
            //患者的药品和价格封装到map中
            map.put(medicinePrice.getMedicineId(), medicinePrice.getUnitPrice());

            //患者支付完后，扣除余额
            int row = patientMapper.updateBalanceForMedicine(medicinePrice);
            if(row != 1) {
                Result.build(ResultCodeEnum.ILLEGAL_OPERATION, "该用户余额不足，请先充值");
            }

        }
        //记录缴费日志
        //从hashmap中取出所有药品价格，计算总价格
        Integer totalPrice = 0;
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            totalPrice += entry.getValue();
        }
        BuyMedicineLog buyMedicineLog = new BuyMedicineLog();
        buyMedicineLog.setPatientName(patient.getPatientName());
        buyMedicineLog.setPaymentAmount(BigDecimal.valueOf(totalPrice));
        buyMedicineLog.setCreateTime(LocalDateTime.now());
        buyMedicineLogMapper.insert(buyMedicineLog);

        //更新该患者的缴费状态
        consultationMapper.updatePayStatus(patient.getPatientName());
        return Result.ok(prescriptionPharmacies,"缴费完成该患者开的药品");

    }

    /**
     * 患者获取个人信息
     * @param
     * @return
     */
    @Override
    public Result<Object> getPatientInfo() {
        String token=request.getHeader("Authorization");
        int userId= jwtHelper.getUserId(token);
        LambdaQueryWrapper<Patient> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Patient::getUserId, userId);
        Patient patient = patientMapper.selectOne(queryWrapper);
        return Result.ok(patient, "获取患者个人信息成功");
    }


    /**
     * 用户-患者获取个人信息
     * @param
     * @return
     */
    @Override
    public Result<Object> getUserPatientInfo() {
        String token=request.getHeader("Authorization");
        int userId= jwtHelper.getUserId(token);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserId, userId);
        User user = userMapper.selectOne(queryWrapper);
        return Result.ok(user, "获取患者个人信息成功");
    }

    /**
     * 患者获取所开药品
     * @return
     */
    @Override
    public List<PrescriptionPharmacy> getPharmacyByPatient() {
        String token=request.getHeader("Authorization");
        int userId= jwtHelper.getUserId(token);
        LambdaQueryWrapper<Patient> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Patient::getUserId, userId);
        Patient patient = patientMapper.selectOne(queryWrapper);
        LambdaQueryWrapper<Prescription> prescriptionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        prescriptionLambdaQueryWrapper.eq(Prescription::getPatientId, patient.getPatientId());
        Prescription prescription = prescriptionMapper.selectOne(prescriptionLambdaQueryWrapper);
        LambdaQueryWrapper<PrescriptionPharmacy> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PrescriptionPharmacy::getPrescriptionId, prescription.getPrescriptionId());
        List<PrescriptionPharmacy> prescriptionPharmacies = prescriptionPharmacyMapper.selectList(wrapper);
        List<PrescriptionPharmacy> pharmacyList = new ArrayList<>();

        for (PrescriptionPharmacy prescriptionPharmacy : prescriptionPharmacies) {
            pharmacyList.add(prescriptionPharmacy);
        }
        return pharmacyList;
    }

    @Override
    public List<Patient> searchPatient(String key) {
        List<Patient> list = patientMapper.search(key);
        return list;
    }

    @Override
    public Result<Object> getAllBuyLog(LogPageQueryDto logPageQueryDto) {
        int pageNum=logPageQueryDto.getPageNum();
        int pageSize=logPageQueryDto.getPageSize();
        //创建page对象
        Page<BuyMedicineLog> logPage=new Page<>(pageNum,pageSize);
        IPage<BuyMedicineLog>logIPage=buyMedicineLogMapper.selectPage(logPage,null);

        return Result.build(logIPage,200,"获取所有管理员信息成功");
    }

    @Override
    public Result<Object> deleteLog(int id) {
        LambdaQueryWrapper<BuyMedicineLog> lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BuyMedicineLog::getId,id);
        int is_success=buyMedicineLogMapper.delete(lambdaQueryWrapper);
        if(is_success>0){
            return Result.build(null,200,"删除购买记录信息成功");
        }else{
            return Result.build(null,200,"删除购买记录信息失败");

        }
    }

    @Override
    public List<BuyMedicineLog> searchLog(String key) {
        List<BuyMedicineLog> list = buyMedicineLogMapper.search(key);
        return list;
    }
}
